github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/namespaced_taskqueued_cntr/namespace taskqueue ioWriteString.go (about) 1 package namespaced_taskqueued_cntr 2 3 import ( 4 "io" 5 "net/http" 6 //"net/url" 7 8 "fmt" 9 "time" 10 11 "github.com/pbberlin/tools/net/http/loghttp" 12 13 "appengine" 14 "appengine/datastore" 15 "appengine/taskqueue" 16 ) 17 18 type Counter struct { 19 Count int64 20 } 21 22 const nscStringKey = "singularKey" 23 const nscKind = "NamespaceCounter" // namespace counter kind 24 25 const altNamespace = "ns01" 26 27 func agnosticIncrement(c appengine.Context) error { 28 29 key := datastore.NewKey(c, nscKind, nscStringKey, 0, nil) 30 31 return datastore.RunInTransaction(c, func(c appengine.Context) error { 32 var ctr Counter 33 err := datastore.Get(c, key, &ctr) 34 if err != nil && err != datastore.ErrNoSuchEntity { 35 return err 36 } 37 ctr.Count++ 38 _, err = datastore.Put(c, key, &ctr) 39 c.Infof("+1") 40 return err 41 }, nil) 42 } 43 44 func agnosticReadReset(c appengine.Context, doReset bool) (int64, error) { 45 46 key := datastore.NewKey(c, nscKind, nscStringKey, 0, nil) 47 48 var ctrRd Counter 49 err := datastore.Get(c, key, &ctrRd) 50 if err != nil && err != datastore.ErrNoSuchEntity { 51 return 0, err 52 } 53 54 if doReset { 55 var ctrSt Counter 56 ctrSt.Count = -1 57 _, err = datastore.Put(c, key, &ctrSt) 58 } 59 60 return ctrRd.Count, err 61 } 62 63 func readBothNamespaces(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { 64 65 lg, b := loghttp.BuffLoggerUniversal(w, r) 66 _ = b 67 68 var c1, c2 int64 69 var s1, s2 string 70 var err error 71 var reset bool = false 72 73 p := r.FormValue("reset") 74 if p != "" { 75 reset = true 76 } 77 78 c := appengine.NewContext(r) 79 c1, err = agnosticReadReset(c, reset) 80 lg(err) 81 82 { 83 c, err = appengine.Namespace(c, altNamespace) 84 lg(err) 85 c2, err = agnosticReadReset(c, reset) 86 lg(err) 87 } 88 89 s1 = fmt.Sprintf("%v", c1) 90 s2 = fmt.Sprintf("%v", c2) 91 92 io.WriteString(w, "|"+s1+"| |"+s2+"|") 93 if reset { 94 io.WriteString(w, " and reset") 95 } 96 97 } 98 99 func incrementBothNamespaces(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { 100 101 lg, b := loghttp.BuffLoggerUniversal(w, r) 102 _ = b 103 104 c := appengine.NewContext(r) 105 err := agnosticIncrement(c) 106 lg(err) 107 108 { 109 c, err := appengine.Namespace(c, altNamespace) 110 lg(err) 111 err = agnosticIncrement(c) 112 lg(err) 113 } 114 115 s := `counters updates für ns='' and ns='ns01'.` + "\n" 116 io.WriteString(w, s) 117 readBothNamespaces(w, r, m) 118 119 } 120 121 func queuePush(w http.ResponseWriter, r *http.Request, mx map[string]interface{}) { 122 123 lg, b := loghttp.BuffLoggerUniversal(w, r) 124 _ = b 125 126 c := appengine.NewContext(r) 127 128 m := map[string][]string{"counter_name": []string{nscStringKey}} 129 t := taskqueue.NewPOSTTask("/_ah/namespaced-counters/queue-pop", m) 130 131 taskqueue.Add(c, t, "") 132 133 c, err := appengine.Namespace(c, altNamespace) 134 lg(err) 135 taskqueue.Add(c, t, "") 136 137 io.WriteString(w, "tasks enqueued\n") 138 139 io.WriteString(w, "\ncounter values now: \n") 140 readBothNamespaces(w, r, mx) 141 142 io.WriteString(w, "\n\n...sleeping... \n") 143 time.Sleep(time.Duration(400) * time.Millisecond) 144 readBothNamespaces(w, r, mx) 145 146 } 147 148 func queuePop(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { 149 150 lg, b := loghttp.BuffLoggerUniversal(w, r) 151 _ = b 152 153 c := appengine.NewContext(r) 154 err := agnosticIncrement(c) 155 c.Infof("qp") 156 lg(err) 157 } 158 159 func init() { 160 http.HandleFunc("/namespaced-counters/increment", loghttp.Adapter(incrementBothNamespaces)) 161 http.HandleFunc("/namespaced-counters/read", loghttp.Adapter(readBothNamespaces)) 162 163 http.HandleFunc("/_ah/namespaced-counters/queue-pop", loghttp.Adapter(queuePop)) 164 http.HandleFunc("/namespaced-counters/queue-push", loghttp.Adapter(queuePush)) 165 166 }